package com.seahorse.youliao.security;

import com.seahorse.youliao.util.JwtTokenUtils;
import com.seahorse.youliao.utils.SpringContextUtils;
import com.zengtengpeng.operation.RedissonObject;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ProjectName: youliao
 * @Package: com.seahorse.youliao.security
 * @ClassName: JwtTokenAuthenticationFilter
 * @Description: 登录认证检查过滤器
 * <p>
 * 访问接口的时候，登录认证检查过滤器 JwtTokenAuthenticationFilter 会拦截请求校验令牌和登录状态，并根据情况设置登录状态。
 * @author:songqiang
 * @Date:2020-01-10 10:03
 **/
public class JwtTokenAuthenticationFilter extends OncePerRequestFilter {


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        //获取登录接口
        String requestUrl = request.getRequestURI();
        // 如果不为登录接口 则处理token
        if (!requestUrl.endsWith("/login")) {

            // 获取token, 并检查登录状态
            String token = request.getHeader("token");

            // token未过期
            if (token != null && !JwtTokenUtils.isTokenExpired(token)) {

                RedissonObject redissonObject = (RedissonObject) SpringContextUtils.getBeanByClass(RedissonObject.class);
                //缓存中拿取数据
                JwtUserRedis jwtUserRedis = redissonObject.getValue("user:"+token);

                //没有获取到值
                if (jwtUserRedis == null) {
                    chain.doFilter(request,response);
                    return;
                }
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(jwtUserRedis.getUsername(),null,jwtUserRedis.getAuthorities());
                // 认证放入线程
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
            chain.doFilter(request,response);
        }else{
            chain.doFilter(request,response);
        }

    }

}
